package org.geometerplus.fbreader.formats.txt;


import org.geometerplus.fbreader.book.AbstractBook;
import org.geometerplus.fbreader.book.ReadBook;
import org.geometerplus.fbreader.bookmodel.BookModel;
import org.geometerplus.fbreader.fbreader.FBReaderApp;
import org.geometerplus.fbreader.formats.BookReader;
import org.geometerplus.fbreader.formats.BookReadingException;
import org.geometerplus.fbreader.formats.NativeFormatPlugin;
import org.geometerplus.zlibrary.core.encodings.EncodingCollection;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.core.filesystem.ZLTxtFile;
import org.geometerplus.zlibrary.core.util.SystemInfo;
import org.geometerplus.zlibrary.core.util.ZLArrayUtils;
import org.geometerplus.zlibrary.text.view.ZLTextPosition;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TxtPlugin extends NativeFormatPlugin {

    private static final int BUFF_SIZE = 512 * 1024;

    private static byte[] readBuffer = new byte[BUFF_SIZE];

    public TxtPlugin(SystemInfo systemInfo) {
        super(systemInfo, ZLTxtFile.ExtentionName);
    }

    @Override
    public String readAnnotation(ZLFile file) {
        return null;
    }

    @Override
    public int priority() {
        return 0;
    }

    @Override
    public EncodingCollection supportedEncodings() {
        return null;
    }

    @Override
    public void readMetainfo(ReadBook book) throws BookReadingException {
//        book.setTitle(book.File.getBookName());
    }


    @Override
    public void detectLanguageAndEncoding(AbstractBook book) throws BookReadingException {

    }


    private byte[] myUnderflowByteBuffer = new byte[4];
    private int myUnderflowLength;
    private int myTextBufferLength;
    private char[] myTextBuffer = new char[512 * 1024];
    CharsetDecoder myByteDecoder = null;

    public final void parseByteData(ChapterParser parser, byte[] data, int start, int length) {
//        final int oldLength = myTextBufferLength;
//        if (myTextBuffer.length < oldLength + length) {
//            myTextBuffer = ZLArrayUtils.createCopy(myTextBuffer, oldLength,
//                    oldLength + length);
//        }
//        final CharBuffer cb = CharBuffer.wrap(myTextBuffer, myTextBufferLength,
//                length);
//
//        if (myUnderflowLength > 0) {
//            int l = myUnderflowLength;
//            while (length-- > 0 && l < 4) {
//                myUnderflowByteBuffer[l++] = data[start++];
//                final ByteBuffer ubb = ByteBuffer.wrap(myUnderflowByteBuffer);
//                myByteDecoder.decode(ubb, cb, false);
//                if (cb.position() != oldLength) {
//                    myUnderflowLength = 0;
//                    break;
//                }
//            }
//            if (length == 0) {
//                myUnderflowLength = l;
//                return;
//            }
//        }
//
//        ByteBuffer bb = ByteBuffer.wrap(data, start, length);
//        myByteDecoder.decode(bb, cb, false);
//        myTextBufferLength = cb.position();
//        int rem = bb.remaining();
//        if (rem > 0) {
//            for (int i = 0, j = start + length - rem; i < rem; ) {
//                myUnderflowByteBuffer[i++] = data[j++];
//            }
//            myUnderflowLength = rem;
//        }
//        parseContentsData(parser, myTextBuffer, oldLength, myTextBufferLength - oldLength);
    }


    /**
     *
     */
    private StringBuilder cacheBuffer = new StringBuilder(1024 * 256);
    static final Pattern p = Pattern.compile("^(\\s|\\t|\\n|\\r){0,50}第(零|一|二|三|四|五|六|七|八|九|十|百|千|[0-9])+(章|节|回|卷|集|幕|计|篇|部)+(.){0,20}(\\s|\\t|\\n|\\r){0,50}$");

    String strTitleContent;

    private void saveChapter(ChapterParser parser, String title, List<String> strContent) {
//        if (title == null || title.equals("")) {
//            title = "第" + (parser.getChapterCount() + 1) + "章";
//        }
//
//        StringBuilder fullContent = new StringBuilder();
//        for (String str : strContent) {
//            if (str.matches("^[ 　]*$")) {
//                continue;
//            }
//            fullContent.append(str);
//            fullContent.append("\n");
//        }
//        if (fullContent.length() > 0) {
//            parser.addChapter(title, fullContent.toString());
//        }
//        fullContent = null;

    }


    private List<String> mContentCache = new ArrayList<String>();
    private String mBookName;

    static Pattern pattern1 = Pattern.compile("[  \t]+");
    static Pattern pattern2 = Pattern.compile("\r+");
    static Pattern pattern3 = Pattern.compile("\n+".intern());

    public static String removeMoreRN(String srcContent) {
//        Matcher matcher2 = pattern2.matcher(srcContent);
//        if (matcher2.find()) {
//            srcContent = matcher2.replaceAll("\n".intern());
//        }
//
//        Matcher matcher3 = pattern3.matcher(srcContent);
//        if (matcher3.find()) {
//            srcContent = matcher3.replaceAll("\n".intern());
//        }
//        return srcContent;
        return null;
    }

    private void parseContentsData(ChapterParser parser, char[] charBuffer, int offset, int length) {

//        if (charBuffer != null) {
//            cacheBuffer.append(charBuffer, offset, length);
//        }
//
//        charBuffer = null;
//        String formatContents = removeMoreRN(cacheBuffer.toString());
//        String[] chapterContents = formatContents.split("\n");
//
//        for (int i = 0; i < chapterContents.length - 1; i++) {
//            Matcher m = p.matcher(chapterContents[i]);
//            if (m.find()) {
//                saveChapter(parser, strTitleContent == null || strTitleContent.equals("") ? mBookName : strTitleContent, mContentCache);
//                strTitleContent = chapterContents[i];
//                mContentCache.clear();
//            } else {
//                mContentCache.add(chapterContents[i]);
//            }
//        }
//        formatContents = null;
//        cacheBuffer.delete(0, cacheBuffer.length());
//        if (chapterContents.length > 0) {
//            cacheBuffer.append(chapterContents[chapterContents.length - 1]);
//        }
    }

    private void parseChaptersAndSplitFullFile(ChapterParser parser, String fullPath, String bookName) {

//        File file = new File(fullPath);
//        FileInputStream input = null;
//        try {
//            input = new FileInputStream(file);
//            int numRead = 0;
//            String encoding = FileLocalCache.getTextCode(fullPath);
//            String textCode = FileLocalCache.coverEncoding(encoding);
//            myByteDecoder = createDecoder(textCode);
//            while ((numRead = input.read(readBuffer, 0, readBuffer.length)) > 0) {
//                parseByteData(parser, readBuffer, 0, numRead);
//            }
//            Matcher m = p.matcher(cacheBuffer.toString());
//
//            if (m.find()) {
//                saveChapter(parser, strTitleContent == null || strTitleContent.equals("") ? bookName : strTitleContent, mContentCache);
//                strTitleContent = cacheBuffer.toString();
//                mContentCache.clear();
//            } else {
//                mContentCache.add(cacheBuffer.toString());
//                saveChapter(parser, strTitleContent == null || strTitleContent.equals("") ? bookName : strTitleContent, mContentCache);
//            }
//            cacheBuffer.delete(0, cacheBuffer.length());
//            parser.saveDir();
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                if (input != null) {
//                    input.close();
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//        System.gc();

    }

    private boolean isNeedChapterParse(long bookId) {
//        return !FileUtils.isFileExist(GlobalConstants.LOCAL_BOOK_PATH + "/" + bookId + "/" + GlobalConstants.DIR_NAME);
        return false;
    }


    protected final CharsetDecoder createDecoder(String encoding)
            throws UnsupportedEncodingException {
        return Charset.forName(encoding).newDecoder()
                .onMalformedInput(CodingErrorAction.REPLACE)
                .onUnmappableCharacter(CodingErrorAction.REPLACE);
    }


    @Override
    public void init(BookReader bookReader, BookModel bookModel) {
        super.init(bookReader, bookModel);

//        MTxtReader txtNovelReader = (MTxtReader) myBookReader;
//        boolean hasDir = false;
//        ZLTxtFile file = (ZLTxtFile) bookReader.getStartFile();
//        ChapterParser parser = new ChapterParser(file.getBookId());
//        List<Chapter> chapters = null;
//        boolean loadDirOk = false;
//        if (parser.hasDir()) {
//            chapters = parser.loadDir();
//        }
//        if (chapters == null || chapters.isEmpty()) {
//            parseChaptersAndSplitFullFile(parser, file.getFullPath(), file.getBookName());
//            chapters = parser.getAllChapters();
//        }
//        txtNovelReader.addChapters(chapters);
//
//        ((FBReaderApp) FBReaderApp.Instance()).IsAutoPayVIPChapter.setValue(true);
//
//        final ZLTxtFile txt17KFile = file;
//
//        String lastReadChapterId = null;
//        ZLTextPosition lastReadPosition = null;
//
//        if (txt17KFile.getStartPositioin() != null) {
//            ZLTextPosition mark = txt17KFile.getStartPositioin();
//            lastReadPosition = mark;
//            lastReadChapterId = lastReadPosition.getTag();
//        } else {
//            lastReadPosition = myBookModel.Book.getStoredPosition();
//            if (lastReadPosition != null) {
//                lastReadChapterId = lastReadPosition.getTag();
//            }
//            txt17KFile.setStartPositioin(lastReadPosition);
//        }
//        Chapter chapter = txtNovelReader.gotoChapterById(lastReadChapterId);
//        chapter = txtNovelReader.gotoChapterById(chapter.getId());
//        if (chapter != null) {
//            txt17KFile.setChapterId(chapter.getId());
//            // LogUtil.e("zhongp","TxtPlugin init >>>>chapter.getName()>>>>>>>>>" + chapter.getName());
//            txt17KFile.setChapterName(chapter.getName());
//            myBookModel.Book.setTitle(chapter.getName());
//        }


    }


    @Override
    public synchronized void readModel(ZLFile file, BookModel model) throws BookReadingException {
//        ZLTxtFile zfile = (ZLTxtFile) model.Book.File;
//        ZLTxtFile readFile = (ZLTxtFile) file;
//        zfile.setChapterId(readFile.getChapterId());
//        zfile.setChapterName(readFile.getChapterName());
//        zfile.setBookName(readFile.getBookName());
//        boolean bo = com.iwanvi.common.utils.FileUtils.isFileExist(((ZLTxtFile) file).getFullPath());
//        if (bo) {
//            zfile.setBookId(((ZLTxtFile) file).getFullPath().hashCode() + "");
//        } else {
//            zfile.setBookId(((ZLTxtFile) file).getFullPath());
//        }
//        model.Book.setTitle(readFile.getChapterName());
        super.readModel(file, model);
    }
}
